import 'dart:async';
import 'dart:io';

// 基础变量与Hello World
void printHelloWorld() {
  print('Hello, World!');
}

// 变量示例
void variableExamples() {
  var name = 'Voyager I';
  var year = 1977;
  var antennaDiameter = 3.7;
  var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
  var image = {
    'tags': ['saturn'],
    'url': '//path/to/saturn.jpg',
  };

  print('\n--- 变量示例 ---');
  print('name: $name');
  print('year: $year');
  print('antennaDiameter: $antennaDiameter');
  print('flybyObjects: $flybyObjects');
  print('image: $image');
}

// 流程控制示例
void processControlExamples() {
  var year = 1977;
  var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];

  print('\n--- 流程控制示例 ---');

  // if-else if 语句
  if (year >= 2001) {
    print('21st century');
  } else if (year >= 1901) {
    print('20th century'); // 输出: 20th century
  }

  // for 循环遍历列表
  print('\nFlyby Objects:');
  for (final object in flybyObjects) {
    print(object);
  }

  // for 循环从 1 到 12
  print('\nMonths:');
  for (int month = 1; month <= 12; month++) {
    print(month);
  }

  // while 循环
  while (year < 2016) {
    year += 1;
  }
  print('\n最终的 year: $year'); // 输出: 2016
}

// 函数示例
void functionExamples() {
  print('\n--- 函数示例 ---');

  // 斐波那契数列
  int fibonacci(int n) {
    if (n == 0 || n == 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
  }

  var result = fibonacci(20);
  print('第 20 个斐波那契数: $result'); // 输出: 6765

  var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
  // 筛选包含 'turn' 的元素
  flybyObjects
      .where((name) => name.contains('turn'))
      .forEach(print); // 输出: Saturn

  // 胖箭头函数
  var add = (int a, int b) => a + b;
  print('两数相加: ${add(3, 5)}'); // 输出: 8
}

// 类定义
class Spacecraft {
  String name;
  DateTime? launchDate; // 允许 null 值

  int? get launchYear => launchDate?.year;

  // 主构造函数需要两个参数：name 和 launchDate（后者可为 null）
  Spacecraft(this.name, this.launchDate);
  Spacecraft.unlaunched(String name) : this(name, null); // 命名构造函数

  void describe() {
    print('\nSpacecraft: $name');
    var launchDate = this.launchDate;
    if (launchDate != null) {
      int years = DateTime.now().difference(launchDate).inDays ~/ 365;
      print('Launched: $launchYear ($years years ago)');
    } else {
      print('Unlaunched');
    }
  }
}

// 枚举类型
enum PlanetType { terrestrial, gas, ice }

enum Planet {
  mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
  venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
  earth(planetType: PlanetType.terrestrial, moons: 1, hasRings: false),
  uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
  neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);

  const Planet({
    required this.planetType,
    required this.moons,
    required this.hasRings,
  });

  final PlanetType planetType;
  final int moons;
  final bool hasRings;

  bool get isGiant =>
      planetType == PlanetType.gas || planetType == PlanetType.ice;
}

// 继承示例：轨道器类
class Orbiter extends Spacecraft {
  double altitude;

  // 子类构造函数传递两个父类参数 + 自身参数
  Orbiter(super.name, super.launchDate, this.altitude);
}

mixin Piloted {
  int astronauts = 1;
  void describeCrew() {
    print('Number of astronauts: $astronauts');
  }
}

class PilotedCraft extends Spacecraft with Piloted {
  PilotedCraft(String name, DateTime launchDate) : super(name, launchDate);
}

// 接口与抽象类
class MockSpaceship implements Spacecraft {
  @override
  String name;
  @override
  DateTime? launchDate;

  MockSpaceship(this.name, this.launchDate);

  @override
  int? get launchYear => launchDate?.year;

  @override
  void describe() {
    print('MockSpaceShip: $name');
    if (launchDate != null) {
      int years = DateTime.now().difference(launchDate!).inDays ~/ 365;
      print('Launched: ${launchDate!.year} ($years years ago)');
    } else {
      print('Unlaunched');
    }
  }
}

abstract class Describable {
  void describe();
  void describeWithEmphasis() {
    print('=========');
    describe();
    print('=========');
  }
}

// 异步操作
Future<void> printWithDelay(String message) async {
  await Future.delayed(const Duration(seconds: 1));
  print(message);
}

Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
  for (final object in objects) {
    await Future.delayed(const Duration(seconds: 1));
    yield '${craft.name} flies by $object';
  }
}

// 异常处理
void exceptionHandling() async {
  var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
  int astronauts = 1; // 避免抛出异常

  if (astronauts == 0) {
    throw StateError('No astronauts.');
  }

  try {
    for (final object in flybyObjects) {
      var file = File('$object.txt');
      if (!await file.exists()) {
        await file.create();
        await file.writeAsString('Description of $object');
      }
      var description = await file.readAsString();
      print(description);
    }
  } on IOException catch (e) {
    print('Could not describe object: $e');
  } finally {
    flybyObjects.clear();
    print('Flyby objects cleared');
  }
}

void main() async {
  printHelloWorld(); // 正确调用 void 函数
  variableExamples(); // 正确调用 void 函数
  processControlExamples(); // 正确调用 void 函数
  functionExamples(); // 正确调用 void 函数
  // 修正后的实例化（传递两个参数给 Spacecraft 构造函数）
  var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
  voyager.describe();

  var voyager3 = Spacecraft.unlaunched('Voyager III'); // 命名构造函数已处理参数
  voyager3.describe();

  // 其他示例（保持不变）
  var orbiter = Orbiter('Hubble', DateTime(1990, 4, 24), 547.0);
  print('\n轨道器名称: ${orbiter.name}，高度: ${orbiter.altitude} km');

  var pilotedCraft = PilotedCraft('ISS', DateTime(2023, 1, 1));
  pilotedCraft.astronauts = 6;
  pilotedCraft.describeCrew();

  var mockSpaceship = MockSpaceship('模拟航天器', DateTime(2023, 1, 1));
  mockSpaceship.describe();

  await printWithDelay('\n--- 延迟1秒 ---');
  var spacecraft = Spacecraft('旅行者号', null); // 允许 launchDate 为 null
  var targets = ['火星', '木星'];
  await for (var msg in report(spacecraft, targets)) {
    print(msg);
  }

  exceptionHandling();
}
